package navgtor

import (
	"gennav/pathtool"
	"path"
	"path/filepath"
)

const (
	// 节点类型：根节点
	NODE_TYPE_ROOT = 0
	// 节点类型：文件
	NODE_TYPE_FILE = 1
	// 节点类型：目录
	NODE_TYPE_FOLDER = 2

	// 空字符串
	EMPTY_STRING = ""
)

type navTree struct {
	name     string     // 文件/目录名
	relPath  string     // 相对路径（仅文件）
	desc     string     // 文件描述（仅文件）
	nodeType int        // 节点类型 - NODE_TYPE_FILE 文件 - NODE_TYPE_FOLDER 目录 - NODE_TYPE_ROOT 根节点
	level    int        // 层级
	children []*navTree // 子节点

	realPath string // 真实文件路径
}

func (root *navTree) addChild(child *navTree) {
	root.children = append(root.children, child)
}

func genNode(name, relPath, desc string, nodeType, level int, realPath string) *navTree {
	node := &navTree{
		name:     name,
		relPath:  relPath,
		desc:     desc,
		nodeType: nodeType,
		level:    level,
		children: []*navTree{},
		realPath: realPath,
	}
	return node
}

// 生成一个NavTree
// @param libpath: library目录的完全路径
func genNavTree(libPath string) (*navTree, error) {
	// 根节点
	root := genNode(EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, NODE_TYPE_ROOT, -1, EMPTY_STRING)

	// 一级目录构建
	priDics, err := pathtool.PriDic(libPath)
	if err != nil {
		return nil, err
	}

	for ind := range priDics {
		// 构建一级目录节点
		name := path.Base(priDics[ind])
		relPath := name
		nodeType := NODE_TYPE_FOLDER
		level := 0

		priNode := genNode(name, relPath, EMPTY_STRING, nodeType, level, priDics[ind])
		root.addChild(priNode)
	}

	// 调用递归构建函数，构建NavTree
	err = buildNavTree(root)
	if err != nil {
		return root, err
	}

	return root, nil
}

// 从根节点开始构建一个NavTree
func buildNavTree(node *navTree) error {
	if node.nodeType == NODE_TYPE_ROOT {
		for ind := range node.children {
			err := buildNavTree(node.children[ind])
			if err != nil {
				return err
			}
		}
		return nil
	}

	// 获取目录下所有路径
	paths, err := pathtool.PriPaths(node.realPath)
	if err != nil {
		return err
	}

	for ind := range paths {
		if pathtool.IsDir(paths[ind]) {
			// 目录，创建一个目录子节点，并递归调用
			name := path.Base(paths[ind])
			relPath := node.relPath + "/" + name
			nodeType := NODE_TYPE_FOLDER
			level := node.level + 1

			child := genNode(name, relPath, name, nodeType, level, paths[ind])

			node.addChild(child)

			err := buildNavTree(child)
			if err != nil {
				return err
			}
		} else {
			suf := filepath.Ext(paths[ind])
			if suf != ".md" {
				continue
			}
			// 文件，创建一个文件子节点
			name := filepath.Base(paths[ind])
			name = pathtool.TrimSuffix(name)
			relPath := node.relPath + "/" + name
			nodeType := NODE_TYPE_FILE
			level := node.level + 1

			child := genNode(name, relPath, name, nodeType, level, paths[ind])

			node.addChild(child)
		}
	}
	return nil
}
